#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stu.h"

int cmd_init(){
	FILE* fp=fopen(PATH_OF_DATA, "w");
	if(fp == NULL){
		perror("[init]数据文件打开失败");
		return -1;
	}
	
	for(int i=0;i<5;i++){
		char name[10];
		sprintf(name,"%d%d%d", i+1,i+1,i+1);
		fprintf(fp, FMT_OF_DATA, i+1, name, rand()%41, rand()%101);
	}

	fclose(fp);
	return 1;
}

int cmd_insert(){
	printf("请输入要插入的学生信息：学号、姓名、年龄和成绩，以空格分割：");
	int id,age,score;
	char name[100];
	scanf("%d %s %d %d", &id,name,&age,&score);
	//
	printf("111\n");
	PLink L=readFromFile();
	printf("222\n");
	if(L == NULL)
		return -1;
	PNode p=(PNode)malloc(sizeof(Node));
	strcpy(p->stu.name,name);
	p->stu.id=id;
	p->stu.age=age;
	p->stu.score=score;
	link_rearInsert(L, p);
	//写入到文件
	clearAndWrite2File(L);
	//
	link_destroy(L);
	return 1;
}

int cmd_printAll(){
	FILE *fp=fopen(PATH_OF_DATA, "r");
	if(fp == NULL){
		perror("[printAll]数据文件打开失败");
		return -1;
	}
	
	printf("学号\t姓名\t年龄\t成绩\n");
	Stu s;
	while((fscanf(fp,FMT_OF_DATA,&s.id,s.name,&s.age,&s.score))!=EOF){
		printf("%3d\t%s\t%3d\t%3d\n", s.id,s.name,s.age,s.score);
	}

	fclose(fp);
	return 1;
}

int cmd_deleteByID(){
	int id;
	printf("请输入要删除信息的学生ID:");
	scanf("%d", &id);
	//从文件中读出所有数据
	printf("要删除的学生ID=[%d]\n", id);
	PLink L=readFromFile();
	if(L == NULL)
		return -1;
	printf("文件读取成功\n");

	//删除内存中匹配的数据
	printf("删除文件数据：开始\n");
	int cnt=link_deleteByID(L,id);
	//以覆盖的方式写入到文件中
	printf("内存中删除完成,[%d]！！\n", L->len);
	PNode p=L->next;
	for(int i=0;i<L->len;i++){
		printf("%d %s\n", p->stu.id, p->stu.name);
		p=p->next;
	}
	clearAndWrite2File(L);
	// 销毁链表	
	link_destroy(L);
	// 打印结果
	printf("[%d]条数据已经删除\n", cnt);
	return 1;
}

int cmd_updateByID(){
	printf("请输入待更改的学生的ID号:");
	int id;
	scanf("%d", &id);
	//从文件中读取
	PLink L = readFromFile();
	//找到匹配的节点号
	PNode p =link_findById(L, id);
	if(p==NULL){
		printf("修改失败！！没有找到id为[%d]的学生信息\n", id);
	}else{
		//修改内容
		printf("请输入学生姓名、年龄和成绩，以空格隔开: ");
		scanf("%s %d %d", p->stu.name,&p->stu.age,&p->stu.score);
		//写回到文件
		clearAndWrite2File(L);
	}
	//释放资源
	link_destroy(L);
	return 1;
}

int cmd_selectByID(){
	printf("请输入待查询的学生的ID号:");
	int id;
	scanf("%d", &id);
	//从文件中读取
	PLink L = readFromFile();
	//找到匹配的节点号
	PNode p =link_findById(L, id);
	if(p==NULL){
		printf("查询失败！！没有找到id为[%d]的学生信息\n", id);
	}else{
		printf("查询成功！！！\n");
		printf("学生ID: %d\n", p->stu.id);
		printf("姓名: %s\n", p->stu.name);
		printf("年龄: %d\n", p->stu.age);
		printf("成绩: %d\n", p->stu.score);
	}
	//释放资源
	link_destroy(L);
	return 1;
}

int cmd_sortedByScore(){
	PLink L = readFromFile();
	//排序
	for(int i=0;i<L->len;i++){
		PNode pre=L->next;
		for(int j=1;j<L->len-i;j++){
			if(pre->stu.score > pre->next->stu.score){
				int temp=pre->stu.score;
				pre->stu.score=pre->next->stu.score;
				pre->next->stu.score=temp;
			}	
			pre=pre->next;
		}
	}

	//打印
	printf("内存中排序的结果如下：\n");
	printf("学号\t姓名\t年龄\t成绩\n");
	PNode p=L->next;
	for(int i=0;i<L->len;i++){
		Stu s=p->stu;
		printf("%3d\t%s\t%3d\t%3d\n", s.id,s.name,s.age,s.score);
		p=p->next;	
	}

	//释放资源
	link_destroy(L);
	return 1;
}

int cmd_exit(){
	printf("程序即将退出\n");
	exit(0);
}

////////////////////////////////////////
PLink readFromFile(){
	FILE *fp=fopen(PATH_OF_DATA, "r");
	if(fp == NULL){
		perror("[readFromFile]读取数据文件失败");
		return NULL;
	}
	//初始化链表
	PLink L=(PLink)malloc(sizeof(Link));
	L->len=0;
	L->next=NULL;

	while(1){
		int id,age,score;
		char name[100];
		int ret=fscanf(fp,FMT_OF_DATA,&id,name,&age,&score);
		if(ret == EOF)
			break;
		//插入到链表中
		PNode p = (PNode)malloc(sizeof(Node));
		p->stu.id=id;
		strcpy(p->stu.name,name);
		p->stu.age=age;
		p->stu.score=score;
		p->next=NULL;
		link_rearInsert(L, p);
	}

	fclose(fp);
	return L;
}

void link_rearInsert(PLink L, PNode p){
	PNode temp=L;
	for(int i=0;i<L->len;i++){
		temp=temp->next;
	}
	temp->next=p;
	p->next=NULL;
	L->len++;
}

int link_deleteByID(PLink L,int id){
	PNode pre=L;//待删除节点的前置节点
	int cnt=0;//记录删除节点数量
	for(int i=0;i<L->len;i++){
		//printf("链表中id=[%d]\n", pre->stu.id);
		if(pre->next->stu.id == id){//删除pre->next
			PNode t=pre->next;
			pre->next=pre->next->next;
			free(t);
			t=NULL;
			cnt++;
			L->len--;
		}
		pre=pre->next;
	}
	return cnt;
}

int clearAndWrite2File(PLink L){
	FILE *fp=fopen(PATH_OF_DATA,"w");
	if(fp == NULL){
		perror("[clearAndWrite2File]数据文件打开失败");
		return -1;	
	}
	PNode p=L->next;
	for(int i=0;i<L->len;i++){
		Stu s=p->stu;
		fprintf(fp, FMT_OF_DATA, s.id, s.name, s.age, s.score);
		p=p->next;
	}
	fclose(fp);
	return 1;
}

void link_destroy(PLink L){
	PNode p=L->next;
	for(int i=0;i<L->len;i++){
		PNode temp=p;
		p=p->next;
		free(temp);
	}
	free(L);
}

PNode link_findById(PLink L,int id){
	PNode p=L->next;
	for(int i=0;i<L->len;i++){
		if(p->stu.id == id)
			return p;
		p=p->next;
	}
	return NULL;
}

